package com.gdsz.libbasic.utils.file


object JsonUtil {

    /**
     * 格式化json字符串
     *
     * @param jsonStr 需要格式化的json串
     * @return 格式化后的json串
     */
    @JvmStatic
    fun formatJson(jsonStr: String?): String {
        if (jsonStr == null || "" == jsonStr) return ""
        val sb = java.lang.StringBuilder()
        var last: Char
        var current = '\u0000'
        var indent = 0
        for (element in jsonStr) {
            last = current
            current = element
            when (current) {
                '{', '[' -> {
                    sb.append(current)
                    sb.append('\n')
                    indent++
                    addIndentBlank(sb, indent)
                }

                '}', ']' -> {
                    sb.append('\n')
                    indent--
                    addIndentBlank(sb, indent)
                    sb.append(current)
                }

                ',' -> {
                    sb.append(current)
                    if (last != '\\') {
                        sb.append('\n')
                        addIndentBlank(sb, indent)
                    }
                }

                else -> sb.append(current)
            }
        }
        return sb.toString()
    }

    /**
     * 添加space
     *
     * @param sb
     * @param indent
     */
    @JvmStatic
    private fun addIndentBlank(sb: StringBuilder, indent: Int) {
        for (i in 0 until indent) {
            sb.append('\t')
        }
    }

    /**
     * http 请求数据返回 json 中中文字符为 unicode 编码转汉字转码
     *
     * @param theString
     * @return 转化后的结果.
     */
    @JvmStatic
    fun decodeUnicode(theString: String?): String {
        if (theString == null) return ""
        var aChar: Char
        val len = theString.length
        val outBuffer = StringBuffer(len)
        var x = 0
        while (x < len) {
            aChar = theString[x]
            if (aChar == '\\') {
                aChar = theString[++x]
                if (aChar == 'u') {
                    var value = 0
                    for (i in 0..3) {
                        aChar = theString[++x]
                        value = when (aChar) {
                            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' -> (value shl 4) + aChar.toInt() - '0'.toInt()
                            'a', 'b', 'c', 'd', 'e', 'f' -> (value shl 4) + 10 + aChar.code - 'a'.toInt()
                            'A', 'B', 'C', 'D', 'E', 'F' -> (value shl 4) + 10 + aChar.code - 'A'.toInt()
                            else -> throw IllegalArgumentException("Malformed \\uxxxx encoding.")
                        }
                    }
                    outBuffer.append(value.toChar())
                } else {
                    when (aChar) {
                        't' -> aChar = '\t'
                        'r' -> aChar = '\r'
                        'n' -> aChar = '\n'
                        'f' -> aChar = '\u000C'
                    }
                    outBuffer.append(aChar)
                }
            } else {
                outBuffer.append(aChar)
            }
            x++
        }
        return outBuffer.toString()
    }
    @JvmStatic
    fun stringToJSON(strJson: String?): String {
        // 计数tab的个数
        var tabNum = 0
        val jsonFormat = StringBuilder()
        val length = strJson?.length ?: return ""

        var last = 0.toChar()
        for (i in 0 until length) {
            val c = strJson[i]
            when (c) {
                '{' -> {
                    tabNum++
                    jsonFormat.append("$c\n")
                    jsonFormat.append(getSpaceOrTab(tabNum))
                }

                '}' -> {
                    tabNum--
                    jsonFormat.append("\n")
                    jsonFormat.append(getSpaceOrTab(tabNum))
                    jsonFormat.append(c)
                }

                ',' -> {
                    jsonFormat.append("$c\n")
                    jsonFormat.append(getSpaceOrTab(tabNum))
                }

                ':' -> {
                    val v = strJson[i - 1]
                    jsonFormat.append(if (v == '\"') "$c " else "$c")
                }

                '[' -> {
                    tabNum++
                    val next = strJson[i + 1]
                    if (next == ']') {
                        jsonFormat.append(c)
                    } else {
                        jsonFormat.append("$c\n")
                        jsonFormat.append(getSpaceOrTab(tabNum))
                    }
                }

                ']' -> {
                    tabNum--
                    if (last == '[') {
                        jsonFormat.append(c)
                    } else {
                        jsonFormat.append("\n${getSpaceOrTab(tabNum)}$c")
                    }
                }

                else -> {
                    jsonFormat.append(c)
                }
            }
            last = c
        }
        return jsonFormat.toString()
    }

    // 是空格还是tab
    @JvmStatic
    private fun getSpaceOrTab(tabNum: Int): String {
        val sbTab = StringBuilder()
        for (i in 0 until tabNum) {
            sbTab.append('\t')
        }
        return sbTab.toString()
    }
}